package pers.vic.boot.security.jwt;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

import org.springframework.stereotype.Service;

import pers.vic.boot.security.constant.AuthSystemConstant;
import pers.vic.boot.security.jwt.enums.JwtVerifyEnum;
import pers.vic.boot.security.redis.RedisService;
import pers.vic.boot.security.util.AuthUtil;

/**
 * @description: JWT注入spring的service
 * @author: Vic.xu
 * @date: 2020年3月20日 上午9:52:51
 */
@Service
public class JwtService {

	@Resource
	private RedisService redisService;

	public JwtService() {

	}

	public JwtService(RedisService redisService) {
		this.redisService = redisService;
	}

	/**
	 * @param token
	 * @return
	 * @description: 校验token的合法性
	 * @author: Vic.xu
	 * @date: 2020年3月20日 上午10:23:40
	 */
	public JwtVerifyEnum verify(String token) {
		boolean result = JwtUtil.verify(token);
		if (!result) {
			return JwtVerifyEnum.INVALID;
		}

		boolean existToken = existToken(token);
		if (!existToken) {
			return JwtVerifyEnum.EXPIRE;
		}
		return JwtVerifyEnum.SUCCESS;
	}

	/**
	 * @param token
	 * @return
	 * @description: token是否在缓存中存在
	 * @author: Vic.xu
	 * @date: 2020年3月20日 上午10:21:54
	 */
	public boolean existToken(String token) {
		Boolean hasKey = redisService.hasKey(AuthUtil.getTokenKey(token));
		return hasKey == null ? false : hasKey;
	}

	/**
	 * 刷新token的过期时间
	 * 
	 * @param token
	 * @return
	 */
	public boolean refreshToken(String token) {
		redisService.expire(AuthUtil.getTokenKey(token), AuthSystemConstant.TOKEN_EXPIRE);
		return true;
	}
	
	/**
	 * 根据用户相关信息 构建token 并且缓存token和用户信息
	 * @param authorityInfo
	 * @return
	 */
	public String buildTokenAndCache(@NotNull AuthorityInfo authorityInfo) {
		String token = JwtUtil.sign(authorityInfo);
		cacheTokenAndAuthorityInfo(token, authorityInfo);
		return token;
	}

	/**
	 * 缓存token以及token对应的用户信息, 理应在登录成功的时候调用此方法
	 * 
	 * @param token
	 * @param authorityInfo
	 * @return
	 */
	public boolean cacheTokenAndAuthorityInfo(String token, @NotNull AuthorityInfo authorityInfo) {
		Integer userId = authorityInfo.getUserId();
		if (userId == null) {
			return false;
		}
		redisService.set(AuthUtil.getTokenKey(token), authorityInfo.getUserId(), AuthSystemConstant.TOKEN_EXPIRE);
		redisService.set(AuthUtil.getUserKey(userId), authorityInfo);
		return true;
	}
	
	/**
	 * 退出登录 : 从REDIS中删除token
	 * @param token
	 * @return
	 */
	public boolean logout(String token) {
		redisService.del(AuthUtil.getTokenKey(token));
		return true;
	}

	/**
	 * 根据token获取REDIS中用户的权限相关信息
	 * @param token
	 * @return
	 */
	public AuthorityInfo getAuthorityInfo(String token) {
		if (!existToken(token)) {
			return new AuthorityInfo();
		}
		Integer userId = (Integer) redisService.get(AuthUtil.getTokenKey(token));
		return getAuthorityInfo(userId);
	}
	
	/**
	 * 根据userId获取REDIS中用户的权限相关信息
	 * @param userId
	 * @return
	 */
	public AuthorityInfo getAuthorityInfo(Integer userId) {
		if(userId == null) {
			return new AuthorityInfo();
		}
		AuthorityInfo info = (AuthorityInfo) redisService.get(AuthUtil.getUserKey(userId));
		return info;
	}
	
}
